package cn.tedu.fcms.customer.associatedaccount.service.impl;

import cn.tedu.fcms.base.enums.associatedaccountenum.AssociatedAccountApprovalStatusEnum;
import cn.tedu.fcms.base.enums.associatedaccountenum.AssociatedAccountStatusEnum;
import cn.tedu.fcms.base.exception.ServiceException;
import cn.tedu.fcms.base.response.StatusCode;
import cn.tedu.fcms.customer.associatedaccount.mapper.AssociatedAccountMapper;
import cn.tedu.fcms.customer.associatedaccount.pojo.dto.AssociatedAccountParam;
import cn.tedu.fcms.customer.associatedaccount.pojo.dto.AssociatedAccountQuery;
import cn.tedu.fcms.customer.associatedaccount.pojo.entity.AssociatedAccount;
import cn.tedu.fcms.customer.associatedaccount.pojo.vo.AssociatedAccountVO;
import cn.tedu.fcms.customer.associatedaccount.service.AssociatedAccountService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.rmi.ServerException;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class AssociatedAccountServiceImpl implements AssociatedAccountService {

    @Autowired
    private AssociatedAccountMapper associatedAccountMapper;


    /**
     * 查询关联账户
     *
     * @param query
     * @return
     */
    @Override
    public List<AssociatedAccountVO> query(AssociatedAccountQuery query) {
        //查询信息
        List<AssociatedAccountVO> cur = associatedAccountMapper.select(query);

        return cur;
    }

    /**
     * 添加关联账户
     *
     * @param param
     * @return
     */
    @Override
    public AssociatedAccountVO add(AssociatedAccountParam param) {
        //TODO
        //  - 关联存款账号只能为非客户本人的本行社账号。
        //  - 已关联的存款账户不得再关联其他借款人。
        //  - 客户名下可关联多个账户，但一个账户只能关联一个客户。

        AssociatedAccount associatedAccount = new AssociatedAccount();
        BeanUtils.copyProperties(param, associatedAccount);
        associatedAccount.setAccountStatus(AssociatedAccountStatusEnum.NOT_EFFECTIVE.getCode());
        associatedAccount.setApprovalStatus(AssociatedAccountApprovalStatusEnum.PENDING.getCode());
        //associatedAccount.setApprovalDate(new Date());
        associatedAccount.setUpdateTime(new Date());
        //associatedAccount.setApprovalNote(null);
        associatedAccountMapper.insert(associatedAccount);
        AssociatedAccountVO associatedAccountVO = new AssociatedAccountVO();
        BeanUtils.copyProperties(associatedAccount, associatedAccountVO);
        return associatedAccountVO;
    }

    /**
     * 更新关联账户
     *
     * @param param
     * @return
     */
    @Override
    public AssociatedAccountVO update(AssociatedAccountParam param) {
        AssociatedAccountVO associatedAccountVO = returnVO(param.getApplicationId());
        String approvalStatus = associatedAccountVO.getApprovalStatus();
        if (approvalStatus.equals(AssociatedAccountApprovalStatusEnum.APPROVED.getCode()) || approvalStatus.equals(AssociatedAccountApprovalStatusEnum.RETURNED.getCode())) {
            AssociatedAccount associatedAccount = new AssociatedAccount();
            BeanUtils.copyProperties(param, associatedAccount);
            associatedAccount.setUpdateTime(new Date());
            associatedAccount.setApprovalStatus(AssociatedAccountApprovalStatusEnum.INITIATED.getCode());
            associatedAccountMapper.update(associatedAccount);
            return returnVO(param.getApplicationId());
        }

        throw new ServiceException(StatusCode.NOT_AN_INITIATED_OR_RETURNED);
    }


    /**
     * 移除关联账户
     *
     * @param applicationId
     * @return
     */
    @Override
    public AssociatedAccountVO remove(Long applicationId) {
        AssociatedAccountVO vo = returnVO(applicationId);
        if (vo.getAccountStatus().equals(AssociatedAccountStatusEnum.EFFECTIVE.getCode())) {
            AssociatedAccount associatedAccount = new AssociatedAccount();
            BeanUtils.copyProperties(vo, associatedAccount);
            associatedAccount.setUpdateTime(new Date());
            associatedAccount.setAccountStatus(AssociatedAccountStatusEnum.EXPIRED.getCode());
            associatedAccountMapper.update(associatedAccount);
            BeanUtils.copyProperties(associatedAccount, vo);
            //associatedAccountMapper.deleteById(applicationId);
            return vo;
        }
        throw new ServiceException(StatusCode.NOT_EFFECTIVE);
    }

    /**
     * 提交审批
     *
     * @param applicationId
     * @return
     */
    @Override
    public AssociatedAccountVO submitApproval(Long applicationId) {
        AssociatedAccount associatedAccount = new AssociatedAccount();
        associatedAccount.setApplicationId(applicationId);
        associatedAccount.setUpdateTime(new Date());
        associatedAccount.setApprovalStatus(AssociatedAccountApprovalStatusEnum.INITIATED.getCode());
        associatedAccountMapper.update(associatedAccount);
        return returnVO(applicationId);
    }

    /**
     * 审批
     *
     * @param param
     * @return
     */
    @Override
    public AssociatedAccountVO approve(AssociatedAccountParam param) {
        AssociatedAccount associatedAccount = new AssociatedAccount();
        BeanUtils.copyProperties(param, associatedAccount);
        associatedAccount.setUpdateTime(new Date());
        associatedAccount.setApprovalDate(new Date());
        if (param.getApprovalStatus().equals(AssociatedAccountApprovalStatusEnum.APPROVED.getCode())) {
            associatedAccount.setAccountStatus(AssociatedAccountStatusEnum.EFFECTIVE.getCode());
            associatedAccountMapper.update(associatedAccount);
        } else {
            associatedAccount.setAccountStatus(AssociatedAccountStatusEnum.NOT_EFFECTIVE.getCode());
            //associatedAccount.setApprovalNote(param.getApprovalNote());
            associatedAccountMapper.update(associatedAccount);
        }
        return returnVO(param.getApplicationId());
    }

    /**
     * 删除账户关联
     *
     * @param applicationId
     * @return
     */
    @Override
    public AssociatedAccountVO delete(Long applicationId) {
        AssociatedAccountVO associatedAccountVO = returnVO(applicationId);
        String status = associatedAccountVO.getApprovalStatus();
        if (status.equals(AssociatedAccountApprovalStatusEnum.PENDING.getCode()) || status.equals(AssociatedAccountApprovalStatusEnum.RETURNED.getCode())) {
           /* AssociatedAccount associatedAccount = new AssociatedAccount();
            associatedAccount.setApplicationId(applicationId);
            associatedAccount.setUpdateTime(new Date());
            associatedAccount.setCustomerId(null);
            associatedAccount.setAccountStatus(AssociatedAccountStatusEnum.DELETED.getCode());*/
            associatedAccountMapper.deleteById(applicationId);
            return associatedAccountVO;
        }
        throw new ServiceException(StatusCode.NOT_PENDING_OR_RETURNED);
    }

    private AssociatedAccountVO returnVO(Long applicationId) {
        AssociatedAccountQuery query = new AssociatedAccountQuery();
        query.setApplicationId(applicationId);
        List<AssociatedAccountVO> vos = associatedAccountMapper.select(query);
        if (!vos.isEmpty()) {
            return vos.get(0);
        }
        return null;
    }
}
